package com.stone.action;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.stone.model.Photo;
import com.stone.model.Provider;
import com.stone.model.ProviderStone;
import com.stone.model.Recommend;
import com.stone.model.Stone;
import com.stone.service.IProviderService;
import com.stone.service.IRecommendService;
import com.stone.service.IStoneService;
import com.stone.utils.Page;

public class StoneAction extends ActionSupport {
	/**
	 * 
	 */
	private static final long serialVersionUID = -1249362624771060275L;
	private Stone stone;
	private List<Photo> photos = new ArrayList<Photo>();
	private long stoneId;
	private int pageno;
	private int totalpageno;
	private int currentpageno;
	private Page page;
	private String query;
	private List<Stone> list;
	/*Search time*/
	private String timeStr;
	private boolean hasQueue = false;
	private boolean mainSearch = false;
	/*Max Number Of Recently Visit Stone*/
	private final int MAXRECENTLY = 3;
	/*Max Number Of Likely Stone*/
	private final int MAXLIKELY = 6;
	/*Most likely Stone list*/
	private List<Stone> likelyList;
	/* DI  service */
	private IStoneService stoneService;
	private IProviderService providerService;
	private IRecommendService recommendService; 
	/* action method  starts*/
	/**
	 * 
	 */
	public String saveStone(){
		//System.out.println(stone.getChineseName());
		stone = stoneService.addStone(stone);
		return "success";
	}
	/**
	 * 
	 * @return
	 */
	public String showNewUploadStones(){
		if(this.pageno!=1){
			this.pageno=getPageNo(this.pageno,this.totalpageno);
		}	
		page=this.stoneService.getNewUploadStones(pageno, 16);
		this.totalpageno=page.getTotalPages();
		this.currentpageno=page.getCurrentPage();
		setQueue();
		checkPopular();
		return "success";
	}
	
	/**
	 * @return
	 */
	public String showVisitMostStones(){
		if(this.pageno!=1){
			this.pageno=getPageNo(this.pageno,this.totalpageno);
		}	
		//page=this.stoneService.getVisitMostStones(pageno, 16);
		page=this.stoneService.getVisitMostDisplayStones(pageno, 16);
		this.totalpageno=page.getTotalPages();
		this.currentpageno=page.getCurrentPage();	
		setQueue();
		checkPopular();
		return "success";
	}
	
	/**
	 * 
	 * @return
	 */
	public String searchStone(){
		Map session = ActionContext.getContext().getSession();
		session.put("stone",stone);
		return searchStoneByNew();
	}
	/**
	 * 
	 * @return
	 */
	public String searchStoneByNew(){
		Map session = ActionContext.getContext().getSession();
		stone = (Stone) session.get("stone");
		if(this.pageno!=1){
			this.pageno=getPageNo(this.pageno,this.totalpageno);
		}	
		page=this.stoneService.searchStoneByNew(stone,pageno, 16);
		stone = new Stone();
		this.totalpageno=page.getTotalPages();
		this.currentpageno=page.getCurrentPage();	
		setQueue();
		checkPopular();
		return "success";
	}
	/**
	 * 
	 * @return== */
	public String searchStoneByVisit(){
		Map session = ActionContext.getContext().getSession();
		stone = (Stone) session.get("stone");
		if(this.pageno!=1){
			this.pageno=getPageNo(this.pageno,this.totalpageno);
		}	
		page=this.stoneService.searchStoneByVisit(stone,pageno, 16);
		this.totalpageno=page.getTotalPages();
		this.currentpageno=page.getCurrentPage();	
		setQueue();
		checkPopular();
		return "success";
	}
	/**
	 * 
	 * @return
	 */
	public String highSearchStone(){
		String path = ServletActionContext.getRequest().getRealPath("");
		if(stoneService.createIndex(path)){
//			long begin = new Date().getTime();
			if(this.pageno!=1){
				this.pageno=getPageNo(this.pageno,this.totalpageno);
			}	
			try {
				if(!mainSearch)
					this.query = new String(ServletActionContext.getRequest().getParameter("query").getBytes("ISO-8859-1"),"UTF-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			long begin = new Date().getTime();
			if(query.trim().equals(""))
			{
				//page = stoneService.getVisitMostStones(pageno, 15);
				page = stoneService.getVisitMostDisplayStones(pageno, 15);
			}
			else
				page = stoneService.getHighSearchStone(path,query,pageno,15);
			DecimalFormat df = new DecimalFormat("#0.000");
			long end = new Date().getTime();
			double time = (double) (end - begin) / 1000;
			timeStr = df.format(time);
			this.totalpageno=page.getTotalPages();
			this.currentpageno=page.getCurrentPage();	
		}
		setQueue();
		checkPopular();
		return "success";
	}
	/**
	 * 通过页面传来的pageno来决定当前页数
	 * @param pageNo
	 * @param totalpageno
	 * @return
	 */
	public int getPageNo(int pageNo,int totalpageno){
		if(pageNo>totalpageno){
			pageNo = totalpageno;
		}
		if(pageNo<=0){
			return 1;
		}
		return pageNo;
	}
	
	public String toStoneDetail(){		
		this.stone = this.stoneService.findStoneById(this.stoneId);
		setQueue();
		checkPopular();
		return "success";
	}
	/**
	 * 通过页面传来stoneId
	 * @return
	 */
	public String toStoneCompany(){
		stone = stoneService.getStoneById(stoneId);
		stone.setVisit(stone.getVisit()+1);
		stoneService.updateStone(stone);
		stone = stoneService.getStoneById(stone.getId());
		Map session = ActionContext.getContext().getSession();
		Queue<Stone> queue = (Queue<Stone>) session.get("recent");
		if(queue==null){
			queue = new ArrayBlockingQueue<Stone>(MAXRECENTLY);
		}
		if(!queue.contains(stone)&&!queue.offer(stone)){
			queue.poll();
			queue.add(stone);
		}
		session.put("recent", queue);
		likelyList = stoneService.getLikelyStones(stone, MAXLIKELY);
		setQueue();
		checkPopular();
		checkRecommend();
//		stone.getPhotos();
		this.photos = this.stoneService.findPhotosByStoneId(stone.getId());
		this.page = this.stoneService.searchCompanyByStone(stone, 1,15);
		for(int i=0;i<this.page.getList().size();i++){
			ProviderStone ps = (ProviderStone) this.page.getList().get(i);
			Provider p = providerService.findProviderById(ps.getProvider().getId());
			((ProviderStone) this.page.getList().get(i)).setProvider(p);
		}
		ServletActionContext.getRequest().setAttribute("pageBean", this.page);
		return "success";
	}
	/**
	 * Get Visit Stone from Session Scop
	 */
	private void setQueue(){
		Map session = ActionContext.getContext().getSession();
		Queue<Stone> queue = (Queue<Stone>)session.get("recent");
		if(queue==null){
			queue = new ArrayBlockingQueue<Stone>(MAXRECENTLY);
			session.put("recent", queue);
		}
		hasQueue = (queue.size()>0)?true:false;
	}
	/**
	 *  check whether the popular stones are in the session 
	 */
	private void checkPopular(){
		Map session = ActionContext.getContext().getSession();
		if(session.get("popular")==null){
			//List<Stone> popularStones = stoneService.getVisitMostStones(1, 6).getList();
			List<Stone> popularStones = stoneService.getVisitMostDisplayStones(1, 6).getList();
			session.put("popular", popularStones);
		}
	}
	/**
	 * 
	 */
	private void checkRecommend(){
		Map session = ActionContext.getContext().getSession();
		if(session.get("recommend")==null){
			List<Recommend> recommendStones = recommendService.findAllRecommend();
			session.put("recommend", recommendStones);
		}
	}
	/*getter setter*/
	public Stone getStone() {
		return stone;
	}

	public void setStone(Stone stone) {
		this.stone = stone;
	}

	public IStoneService getStoneService() {
		return stoneService;
	}

	public void setStoneService(IStoneService stoneService) {
		this.stoneService = stoneService;
	}

	public int getPageno() {
		return pageno;
	}

	public void setPageno(int pageno) {
		this.pageno = pageno;
	}

	public int getTotalpageno() {
		return totalpageno;
	}

	public void setTotalpageno(int totalpageno) {
		this.totalpageno = totalpageno;
	}

	public int getCurrentpageno() {
		return currentpageno;
	}
	public void setCurrentpageno(int currentpageno) {
		this.currentpageno = currentpageno;
	}
	public Page getPage() {
		return page;
	}
	public void setPage(Page page) {
		this.page = page;
	}
	public long getStoneId() {
		return stoneId;
	}
	public void setStoneId(long stoneId) {
		this.stoneId = stoneId;
	}
	public List<Photo> getPhotos() {
		return photos;
	}
	public void setPhotos(List<Photo> photos) {
		this.photos = photos;
	}
	public IProviderService getProviderService() {
		return providerService;
	}
	public void setProviderService(IProviderService providerService) {
		this.providerService = providerService;
	}
	
	public String getQuery() {
		return query;
	}
	public void setQuery(String query) {
		this.query = query;
	}
	public List<Stone> getList() {
		return list;
	}
	public void setList(List<Stone> list) {
		this.list = list;
	}
	public List<Stone> getLikelyList() {
		return likelyList;
	}
	public boolean isHasQueue() {
		return hasQueue;
	}
	public String getTimeStr() {
		return timeStr;
	}
	public void setMainSearch(boolean mainSearch) {
		this.mainSearch = mainSearch;
	}
	public void setRecommendService(IRecommendService recommendService) {
		this.recommendService = recommendService;
	}
}
